import 'dart:convert';

import 'package:flutter_wear_app/utils/event_bus.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';

class XMqttClient {
  static XMqttClient? _instance;
  static bool _isInitialized = false;

  late String _host;
  late String _cid;
  late int _port;
  late String _username;
  late String _password;
  late MqttClient? client;

  // 私有构造函数
  XMqttClient._internal();

  // 单例访问入口
  static XMqttClient get instance {
    if (_instance == null) {
      throw Exception('必须先调用initialize方法初始化');
    }
    return _instance!;
  }

  // 初始化方法（替代原有构造函数）
  static void initialize({
    required String host,
    required String cid,
    required int port,
    required String username,
    required String password,
  }) {
    if (_isInitialized) return;

    _instance =
        XMqttClient._internal()
          .._host = host
          .._cid = cid
          .._port = port
          .._username = username
          .._password = password
          .._initMqtt();

    _isInitialized = true;
  }

  // 初始化MQTT连接
  Future<void> _initMqtt() async {
    print('初始化MQTT连接');
    client = await _connect();
  }

  Future<MqttClient> _connect() async {
    final client = MqttServerClient.withPort(_host, _cid, _port);
    // client.logging(on: true);
    client.keepAlivePeriod = 60;
    client.setProtocolV31();

    final connMess = MqttConnectMessage()
        .authenticateAs(_username, _password)
        .withWillTopic('willtopic')
        .withWillMessage('Will message')
        .startClean()
        // .withProtocolName("MQTT")
        // .withProtocolVersion(4)
        .withWillQos(MqttQos.atLeastOnce);
    client.connectionMessage = connMess;

    client.onDisconnected = _onDisconnected;
    client.onConnected = _onConnected;
    client.onSubscribed = _onSubscribed;
    client.pongCallback = _pong;

    try {
      await client.connect();
    } catch (e) {
      print('连接异常: $e');
      client.disconnect();
    }

    client.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) async {
      final recMessage = c![0].payload as MqttPublishMessage;
      final payload = MqttPublishPayload.bytesToStringAsString(
        recMessage.payload.message,
      );
      print('Received message:$payload from topic: ${c[0].topic}');
      final Map<String, dynamic> decodedPayload = {
        ...json.decode(payload),
        'topic': c[0].topic,
      };
      eventBus.emit(
        decodedPayload['todo'].toString(),
        json.encode(decodedPayload),
      );
    });

    return client;
  }

  ///订阅一个主题
  _subscribe(String topic) {
    client?.subscribe(topic, MqttQos.atLeastOnce);
  }

  ///订阅多个主题
  topicSubscribe(List<String> topics) async {
    if (client?.connectionStatus?.state == MqttConnectionState.connected) {
      topics.forEach((topic) {
        _subscribe(topic);
      });
    } else {
      //未连接成功 每隔3s重新订阅
      Future.delayed(const Duration(seconds: 3), () {
        topicSubscribe(topics);
      });
    }
  }

  ///取消订阅
  _unsubscribe() {
    client?.unsubscribe('topic/test');
  }

  ///发布消息
  publish(String topic, String message) {
    final builder = MqttClientPayloadBuilder();
    builder.addString(message);
    client?.publishMessage(topic, MqttQos.atLeastOnce, builder.payload!);
  }

  void disconnect() {
    client?.disconnect();
    client = null;
  }

  void _onConnected() => {print('MQTT client connected')};
  void _onDisconnected() => print('MQTT client disconnected');
  void _onSubscribed(String topic) => print('Subscribed: $topic');
  void _pong() => print('MQTT client pong');

  bool get isConnected =>
      client?.connectionStatus?.state == MqttConnectionState.connected;
}
